package jmind.core.poi;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

import jmind.base.util.DateUtil;
import jmind.base.util.FileUtil;

import org.apache.poi.ss.usermodel.Workbook;

public abstract class Excel {

    public static Excel getExcel(Version version) {
        return version == Version.xls ? XlsExcel.INSTANCE : XlsxExcel.INSTANCE;

    }

    public static Excel getExcel(String fileName) {
        String type = FileUtil.getExtensionName(fileName);
        return getExcel(Version.valueOf(type.toLowerCase()));
    }

    public static enum Version {
        xls, xlsx
    }
    /**
     *
     * @param column 第几列，从0开始
     * @return 返回excel列名
     */
    public static String getColName(int column) {
        // 因为第几列是从0开始，我的算法从1开始，所以需要 +1
        int cn=column+1;
        StringBuilder stringBuilder = new StringBuilder();
        //直到cn为0停止
        while (cn != 0) {
            cn--;
            stringBuilder.append((char) (cn % 26 + 'A'));
            cn /= 26;
        }
        //由于我们计算列名称的顺序是从右往左，因此需要将拼接后的结果反转。
        stringBuilder.reverse();
        return stringBuilder.toString();
    }
    /**
     * 返回一列的excel
     * @param sheetName
     * @param datas
     * @return
     */
    public abstract Workbook exportExcel(String sheetName, List<?> datas);

    public <T> Workbook exportExcel(String sheetName, List<T> dataset, String[] headers) {
        return exportExcel(sheetName, dataset, headers, DateUtil.F24_PATTERN);
    }

    /**
     * 
     * @param sheetName 
     * @param dataset 
     * @param headers 表头
     * @return
     */
    public abstract <T> Workbook exportExcel(String sheetName, List<T> dataset, String[] headers,String dateFormart);

    /**
     * 初始化工作簿
     *
     *            : Excel数据源
     * @param sheetName
     *            : 新建Sheet的名称
     * @param headers
     *            : Sheet各列的标题（第一行各列的名称）
     * @param methods
     *            : Sheet各列的取值方法名（各列的值在objClass中get方法名称）
     */
    public abstract <T> Workbook exportExcel(String sheetName, List<T> dataset, String[] headers, String[] methods,String dateFormart);

    public  <T> Workbook exportExcel(String sheetName, List<T> dataset, String[] headers, String[] methods){
        return exportExcel(sheetName, dataset, headers, methods,DateUtil.F24_PATTERN);
    }

    /**
     * 导出Excel文件 数据源的数据格式为List<Map<String K,String V>>
     * 
     * @param objList
     *            : Excel数据源
     * @param sheetName
     *            : 新建Sheet的名称

     *            : Excel文档保存路径
     */
    public abstract Workbook exportMapExcel(String sheetName, List<Map<String, String>> objList);

    /**
     * 简单读出单列的excel
     * @param in
     * @return
     */
    public abstract List<String> excel2StrList(InputStream in);

    /**
     * 读出 excel 转换成对象。 支持日期格式
    * @param in excel 流
     * @param claz
     * @return
     */
    public <T> List<T> excel2List(InputStream in, Class<T> claz) {
        // 没定义 字段，按bean的顺序读取
        Field[] fields2 = claz.getDeclaredFields();
        String[] fields = new String[fields2.length];
        for (int i = 0; i < fields2.length; i++) {
            fields[i] = fields2[2].getName();
        }
        return excel2List(in, claz, fields, 0);
    }

    /**
     * 
     * @param in excel 流
     * @param fields 字段名。excel多余字段用null 占位 。为空时读出excel第一行数据.  start 必须为1
     * @param claz 对象类型
     * @param start 数据开始位置
     * @return
     */
    public abstract <T> List<T> excel2List(InputStream in, Class<T> claz, String[] fields, int start);

    /**
     * 
     * @param excelFile
     * @param strKey 字段顺序
     * @return
     * @throws FileNotFoundException 
     */
    public List<Map<String, String>> excel2Map(String excelFile, String[] strKey) throws FileNotFoundException {
        FileInputStream in = new FileInputStream(excelFile);
        return excel2Map(in, strKey);
    }

    public abstract List<Map<String, String>> excel2Map(InputStream in, String[] strKey);

}
